/**
 * 技能引擎 - 负责技能的管理和执行
 * 采用清晰的技能状态管理和效果计算架构
 */

import { ISkillEngine, ISkill, ISkillResult, IBattleParticipant } from '../architecture/interfaces';
import { SkillType, TargetType, attackKey, Attribute_base } from '../../../shared/face/enums';
import BattleLogger from '../BattleLogger';

/**
 * 技能引擎实现
 */
export class SkillEngine implements ISkillEngine {
    /** 技能注册表 */
    private skillRegistry: Map<string, ISkill> = new Map();
    
    /** 技能配置缓存 */
    private skillConfigs: Map<string, any> = new Map();
    
    /** 技能工厂 */
    private skillFactory: SkillFactory;

    constructor() {
        this.skillFactory = new SkillFactory();
    }

    /**
     * 注册技能
     * @param skill 技能实例
     */
    public registerSkill(skill: ISkill): void {
        if (this.skillRegistry.has(skill.id)) {
            BattleLogger.log('info', '技能已存在，将被覆盖', { skillId: skill.id });
        }
        
        this.skillRegistry.set(skill.id, skill);
        BattleLogger.log('info', '技能注册成功', { 
            skillId: skill.id, 
            skillName: skill.name,
            skillType: skill.type 
        });
    }

    /**
     * 获取技能
     * @param id 技能ID
     * @returns 技能实例或null
     */
    public getSkill(id: string): ISkill | null {
        return this.skillRegistry.get(id) || null;
    }

    /**
     * 获取所有技能
     * @returns 所有技能列表
     */
    public getAllSkills(): ISkill[] {
        return Array.from(this.skillRegistry.values());
    }

    /**
     * 使用技能
     * @param skillId 技能ID
     * @param caster 施法者
     * @param targets 目标列表
     * @returns 技能结果
     */
    public useSkill(skillId: string, caster: IBattleParticipant, targets: IBattleParticipant[]): ISkillResult {
        const skill = this.getSkill(skillId);
        if (!skill) {
            return {
                success: false,
                effects: [],
                damage: 0,
                healing: 0,
                buffs: [],
                description: `技能不存在: ${skillId}`
            };
        }

        if (!skill.isAvailable()) {
            return {
                success: false,
                effects: [],
                damage: 0,
                healing: 0,
                buffs: [],
                description: `技能不可用: ${skill.name}`
            };
        }

        // 验证目标
        if (!this.validateTargets(skill, targets)) {
            return {
                success: false,
                effects: [],
                damage: 0,
                healing: 0,
                buffs: [],
                description: `目标无效: ${skill.name}`
            };
        }

        // 使用技能
        const result = skill.use(caster, targets);
        
        // 记录技能使用
        BattleLogger.log('info', '技能使用', {
            skillId,
            skillName: skill.name,
            casterId: caster.id,
            targetCount: targets.length,
            success: result.success
        });

        return result;
    }

    /**
     * 升级技能
     * @param skillId 技能ID
     * @param expGain 获得的经验
     * @returns 是否升级成功
     */
    public upgradeSkill(skillId: string, expGain: number): boolean {
        const skill = this.getSkill(skillId);
        if (!skill) {
            BattleLogger.log('error', '升级技能失败：技能不存在', { skillId });
            return false;
        }

        const success = skill.upgrade(expGain);
        if (success) {
            BattleLogger.log('info', '技能升级成功', { 
                skillId, 
                skillName: skill.name,
                newLevel: skill.level 
            });
        }

        return success;
    }

    /**
     * 学习技能
     * @param skillId 技能ID
     * @param entity 学习实体
     * @returns 是否学习成功
     */
    public learnSkill(skillId: string, entity: IBattleParticipant): boolean {
        const skill = this.getSkill(skillId);
        if (!skill) {
            BattleLogger.log('error', '学习技能失败：技能不存在', { skillId });
            return false;
        }

        // 这里需要根据具体的实体实现来判断是否可以学习技能
        // 暂时返回true，实际实现中需要检查学习条件
        BattleLogger.log('info', '技能学习成功', { 
            skillId, 
            skillName: skill.name,
            entityId: entity.id 
        });

        return true;
    }

    /**
     * 验证目标是否有效
     * @param skill 技能
     * @param targets 目标列表
     * @returns 是否有效
     */
    private validateTargets(skill: ISkill, targets: IBattleParticipant[]): boolean {
        if (targets.length === 0) {
            return false;
        }

        // 检查目标类型是否匹配
        for (const targetType of skill.targetTypes) {
            const validTargets = targets.filter(target => this.isValidTarget(target, targetType));
            if (validTargets.length === 0) {
                return false;
            }
        }

        return true;
    }

    /**
     * 检查目标是否符合目标类型
     * @param target 目标
     * @param targetType 目标类型
     * @returns 是否有效
     */
    private isValidTarget(target: IBattleParticipant, targetType: TargetType): boolean {
        switch (targetType) {
            case TargetType.敌方:
                return target.team !== 'home';
            case TargetType.我方:
                return target.team === 'home';
            case TargetType.自己:
                return true; // 需要根据具体实现判断
            case TargetType.我方不含自己:
                return target.team === 'home'; // 需要排除自己
            default:
                return true;
        }
    }

    /**
     * 创建技能
     * @param config 技能配置
     * @returns 技能实例
     */
    public createSkill(config: any): ISkill {
        return this.skillFactory.createSkill(config);
    }

    /**
     * 验证技能配置
     * @param config 技能配置
     * @returns 是否有效
     */
    public validateSkill(config: any): boolean {
        return this.skillFactory.validateConfig(config);
    }

    /**
     * 获取技能描述模板
     * @param skillId 技能ID
     * @returns 描述模板
     */
    public getSkillDescriptionTemplate(skillId: string): string {
        const skill = this.getSkill(skillId);
        if (!skill) {
            return '技能不存在';
        }

        return skill.getDescription();
    }

    /**
     * 批量注册技能
     * @param skills 技能列表
     */
    public registerSkills(skills: ISkill[]): void {
        for (const skill of skills) {
            this.registerSkill(skill);
        }
    }

    /**
     * 获取技能统计信息
     * @returns 统计信息
     */
    public getSkillStats(): {
        totalSkills: number;
        skillTypes: Map<SkillType, number>;
        averageLevel: number;
    } {
        const skills = this.getAllSkills();
        const skillTypes = new Map<SkillType, number>();
        let totalLevel = 0;

        for (const skill of skills) {
            const count = skillTypes.get(skill.type) || 0;
            skillTypes.set(skill.type, count + 1);
            totalLevel += skill.level;
        }

        return {
            totalSkills: skills.length,
            skillTypes,
            averageLevel: skills.length > 0 ? totalLevel / skills.length : 0
        };
    }
}

/**
 * 技能工厂 - 负责创建技能实例
 */
class SkillFactory {
    /**
     * 创建技能
     * @param config 技能配置
     * @returns 技能实例
     */
    public createSkill(config: any): ISkill {
        // 这里需要根据配置创建具体的技能实例
        // 暂时返回一个基础技能，实际实现中需要根据配置创建不同类型的技能
        return new BaseSkill(config);
    }

    /**
     * 验证配置
     * @param config 技能配置
     * @returns 是否有效
     */
    public validateConfig(config: any): boolean {
        const requiredFields = ['id', 'name', 'type', 'targetTypes'];
        
        for (const field of requiredFields) {
            if (!config[field]) {
                BattleLogger.log('error', '技能配置缺少必需字段', { field, config });
                return false;
            }
        }

        return true;
    }
}

/**
 * 基础技能类 - 技能的基础实现
 */
export class BaseSkill implements ISkill {
    public id: string;
    public name: string;
    public description: string;
    public type: SkillType;
    public targetTypes: TargetType[];
    public cooldown: number;
    public currentCooldown: number;
    public level: number;
    public maxLevel: number;
    public exp: number;
    public useCount: number;
    public permanentBoosts: Map<string, number>;

    constructor(config: any) {
        this.id = config.id;
        this.name = config.name;
        this.description = config.description || '';
        this.type = config.type;
        this.targetTypes = config.targetTypes || [];
        this.cooldown = config.cooldown || 0;
        this.currentCooldown = 0;
        this.level = config.level || 1;
        this.maxLevel = config.maxLevel || 10;
        this.exp = config.exp || 0;
        this.useCount = config.useCount || 0;
        this.permanentBoosts = new Map();
    }

    public isAvailable(): boolean {
        return this.currentCooldown <= 0;
    }

    public use(caster: IBattleParticipant, targets: IBattleParticipant[]): ISkillResult {
        if (!this.isAvailable()) {
            return {
                success: false,
                effects: [],
                damage: 0,
                healing: 0,
                buffs: [],
                description: `${this.name} 冷却中`
            };
        }

        // 设置冷却
        this.currentCooldown = this.cooldown;
        this.useCount++;

        // 计算效果
        let totalDamage = 0;
        let totalHealing = 0;
        const effects: any[] = [];
        const buffs: any[] = [];

        for (const target of targets) {
            const effect = this.calculateEffect(caster, target);
            if (effect > 0) {
                if (this.type === SkillType.主动技能) {
                    totalDamage += effect;
                } else {
                    totalHealing += effect;
                }
            }
        }

        return {
            success: true,
            effects,
            damage: totalDamage,
            healing: totalHealing,
            buffs,
            description: `${caster.name} 使用 ${this.name}`
        };
    }

    public upgrade(expGain: number): boolean {
        if (this.level >= this.maxLevel) {
            return false;
        }

        this.exp += expGain;
        const expNeeded = this.level * 100;

        if (this.exp >= expNeeded) {
            this.exp -= expNeeded;
            this.level++;
            return true;
        }

        return false;
    }

    public getDescription(): string {
        // 使用技能描述管理器生成动态描述
        const { skillDescriptionManager } = require('./SkillDescriptionManager');
        return skillDescriptionManager.generateDescription(this);
    }

    public calculateEffect(caster: IBattleParticipant, target: IBattleParticipant): number {
        // 基础效果计算
        let baseEffect = 10;
        
        // 等级加成
        baseEffect *= (1 + (this.level - 1) * 0.1);
        
        // 永久提升
        for (const [boostType, amount] of this.permanentBoosts) {
            if (boostType === 'damage' || boostType === 'healing') {
                baseEffect += amount;
            }
        }
        
        return Math.max(0, baseEffect);
    }
} 